/*
 * 版权所有 (C) 2015 知启蒙(ZHIQIM) 保留所有权利。[遇见知启蒙，邂逅框架梦]
 * 
 * https://zhiqim.org/project/zhiqim_framework/zhiqim_orm.htm
 *
 * Zhiqim Orm is licensed under Mulan PSL v2.
 * You can use this software according to the terms and conditions of the Mulan PSL v2.
 * You may obtain a copy of Mulan PSL v2 at:
 *          http://license.coscl.org.cn/MulanPSL2
 * THIS SOFTWARE IS PROVIDED ON AN "AS IS" BASIS, WITHOUT WARRANTIES OF ANY KIND,
 * EITHER EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO NON-INFRINGEMENT,
 * MERCHANTABILITY OR FIT FOR A PARTICULAR PURPOSE.
 * See the Mulan PSL v2 for more details.
 */
package org.zhiqim.orm.impl;

import java.math.BigDecimal;
import java.sql.SQLException;
import java.util.List;

import org.zhiqim.kernel.MultiInstancer;
import org.zhiqim.kernel.extend.HashMapSO;
import org.zhiqim.kernel.extend.HashMapSS;
import org.zhiqim.kernel.extend.HashSetS;
import org.zhiqim.kernel.extend.LinkedMapSO;
import org.zhiqim.kernel.extend.MapSO;
import org.zhiqim.kernel.extend.MapSS;
import org.zhiqim.kernel.logging.Log;
import org.zhiqim.kernel.logging.LogFactory;
import org.zhiqim.kernel.paging.PageBuilder;
import org.zhiqim.kernel.paging.PageResult;
import org.zhiqim.kernel.util.Arrays;
import org.zhiqim.kernel.util.Asserts;
import org.zhiqim.kernel.util.Lists;
import org.zhiqim.kernel.util.Sqls;
import org.zhiqim.kernel.util.Validates;
import org.zhiqim.orm.ORM;
import org.zhiqim.orm.ORMConstants;
import org.zhiqim.orm.ORMException;
import org.zhiqim.orm.ORMI18n;
import org.zhiqim.orm.ORMServer;
import org.zhiqim.orm.ZSQL;
import org.zhiqim.orm.ZTabler;
import org.zhiqim.orm.dbo.Selector;
import org.zhiqim.orm.dbo.Updater;
import org.zhiqim.orm.dbo.UpdaterField;
import org.zhiqim.orm.dbo.defined._Table;
import org.zhiqim.orm.dbo.defined._TableField;
import org.zhiqim.orm.exception.TableNotExistException;

/**
 * 标准类与数据库表映射调用，支持(truncate,exist,insert,replace,update,delete,count,sum,item,list,page)<br><br>
 * truncate,    清除表类对应的表<br>
 * exist,       检查表类对应的表是否存在<br>
 * create       创建表类对应的表
 * insert,      插入表类对应的表一条数据<br>
 * replace,     替换表类对应的表一条数据，根据主键<br>
 * update,      更新表类对应的表一条数据或根据条件更新数据<br>
 * delete,      删除表类对应的表一条数据或根据条件删除数据<br>
 * count,       统计表类对应的表数目<br>
 * sum,         总计表类对应的表数目<br>
 * item,        查询表类对应的表一条数据，根据主键，或根据条件排序取第一条<br>
 * list,        查询表类对应的表列表，或根据条件排序<br>
 * pag,         分页查询表类对应的表列表，指定分页页码和页数目<br>
 *
 * @version v1.0.0 @author zouzhigang 2014-3-21 新建与整理
 * @version v1.2.0 @author zouzhigang 2016-6-27 修改原类名ZTableExcutor为ZTableExecutor，正式使用表类名称
 */
public final class ZTablerImplement extends MultiInstancer implements ZTabler, ORMConstants
{
    private static final Log log = LogFactory.getLog(ZTablerImplement.class);
    
    private final ORMServer server;
    private final ZSQL zSQL;
    private final HashSetS tableExistList;
    private final HashMapSO tableLockMap;
    
    public ZTablerImplement(ORMServer server)
    {
        this.server = server;
        this.zSQL = server.sql();
        this.tableExistList = new HashSetS();
        this.tableLockMap = new HashMapSO();
    }
    
    /**
     * 获取ORM服务器
     * 
     * @return              数据库服务器
     */
    public ORMServer getServer()
    {
        return server;
    }
    
    /*****************************************************/
    //exist 表是否存在
    /*****************************************************/
    
    /**
     * 是否存在[实际表]可替换表
     * 
     * @param table         表类
     * @return              =true表示存在，=false表示不存在
     * @throws ORMException 映射异常
     * @throws SQLException 数据库异常
     */
    public boolean exist(_Table _table) throws ORMException, SQLException
    {
        return exist(_table, null);
    }

    /**
     * 是否存在[实际表]可替换表，支持表名中有多个替换字段，如LOG_TRACE_$MONTH$_$ID$
     * 
     * @param table         表类
     * @param replaceMap    可替换字段表
     * @return              =true表示存在，=false表示不存在
     * @throws ORMException 映射异常
     * @throws SQLException 数据库异常
     */
    public boolean exist(_Table _table, MapSS replaceMap) throws ORMException, SQLException
    {
        ORM.as(_table != null?null:"ZTabler[exist][表定义对象不能为null]");
        
        _table.chkReplace(replaceMap);
        String tableName = Sqls.formatReplaceMap(_table.getTable(), replaceMap);
        boolean exist = zSQL.existTable(tableName);
        if (exist)
            tableExistList.add(tableName);
        
        return exist;
    }
    
    /*****************************************************/
    //create 创建表
    /*****************************************************/
    
    /**
     * 创建[实际表]可替换表，正常创建检查
     * 
     * @param _table        表类
     * @throws ORMException 映射异常
     * @throws SQLException 数据库异常
     */
    public void create(_Table _table) throws ORMException, SQLException
    {
        create(_table, null, false);
    }
    
    /**
     * 创建[实际表]可替换表，正常创建检查，支持表名中有多个替换字段，如LOG_TRACE_$MONTH$_$ID$
     * 
     * @param _table        表类
     * @param replaceMap    可替换字段表
     * @throws ORMException 映射异常
     * @throws SQLException 数据库异常
     */
    public void create(_Table _table, MapSS replaceMap) throws ORMException, SQLException
    {
        create(_table, replaceMap, false);
    }
    
    /**
     * 创建[实际表]可替换表
     * 
     * @param table         表类
     * @param isException   是否异常重建
     * @throws ORMException 映射异常
     * @throws SQLException 数据库异常
     */
    public void create(_Table table, boolean isException) throws ORMException, SQLException
    {
        create(table, null, isException);
    }
    
    /**
     * 创建[表类]对应的[实际表]可替换表，支持表名中有多个替换字段，如LOG_TRACE_$MONTH$_$ID$
     * 
     * @param table         表类
     * @param replaceMap    可替换字段表
     * @param isException   是否异常重建
     * @throws ORMException 映射异常
     * @throws SQLException 数据库异常
     */
    public void create(_Table _table, MapSS replaceMap, boolean isException) throws ORMException, SQLException
    {
        ORM.as(_table != null?null:"ZTabler[create][表定义对象不能为null]");
        
        _table.chkReplace(replaceMap);
        String tableName = Sqls.formatReplaceMap(_table.getTable(), replaceMap);
        if (!isException && tableExistList.contains(tableName))
        {//正常情况的，缓存中存在则认为存在，如果真实不存在的等SQL异常处理，可能会导致并发多个进异常状态
            return;
        }
        
        Object tableLock = getTableLock(tableName);
        synchronized (tableLock)
        {
            if (zSQL.existTable(tableName))
            {//1.如果表真实存在的，加到缓存，这里并发多个会调用SQL到数据库查，有一定的性能影响（但因为表可能被管理员通过数据库直接删除，所以安全情况下还是到数据库查才准确）
                tableExistList.add(tableName);
                return;
            }
            
            if (isException)
            {//2.异常情况的，先删除存在标志，后续线程直接在正常时即进入同步锁状态不会进入SQL异常流程
                tableExistList.remove(tableName);
            }
        
            //3.如果表真实不存在的，则创建，并增加到缓存中
            List<String> sqlList = server.getPolicy().toTableString(_table, replaceMap);
            zSQL.execute(sqlList);
            tableExistList.add(tableName);
        }
        
        log.info("创建表[%s]成功", tableName);
    }
    
    /**
     * 删除[实际表]可替换表
     * 
     * @param table         表类
     * @throws ORMException 映射异常
     * @throws SQLException 数据库异常
     */
    public void drop(_Table _table) throws ORMException, SQLException
    {
        drop(_table, null);
    }
    
    /**
     * 删除[实际表]可替换表，支持表名中有多个替换字段，如LOG_TRACE_$MONTH$_$ID$
     * 
     * @param table         表类
     * @param replaceMap    可替换字段表
     * @throws ORMException 映射异常
     * @throws SQLException 数据库异常
     */
    public void drop(_Table _table, MapSS replaceMap) throws ORMException, SQLException
    {
        ORM.as(_table != null?null:"ZTabler[drop][表定义对象不能为null]");
        
        _table.chkReplace(replaceMap);
        String tableName = Sqls.formatReplaceMap(_table.getTable(), replaceMap);
        if (!zSQL.existTable(tableName))
        {//直接到数据库查
            tableExistList.remove(tableName);
            return;
        }
        
        //删除表和清除缓存
        zSQL.execute("drop table "+tableName+";");
        tableExistList.remove(tableName);
        log.info("删除表[%s]成功", tableName);
    }
    
    /*****************************************************/
    //truncate 清空表
    /*****************************************************/
    
    /**
     * 清空[实际表]
     * 
     * @param _table        表对象
     * @throws ORMException 映射异常
     * @throws SQLException 数据库异常
     */
    public void truncate(_Table _table) throws ORMException, SQLException
    {
        truncate(_table, null);
    }
    
    /**
     * 清空[表类]对应的[实际表]，支持表名中有多个替换字段，如LOG_TRACE_$MONTH$_$ID$
     * 
     * @param _table        表定义对象
     * @param replaceMap    替换表
     * @throws ORMException 映射异常
     * @throws SQLException 数据库异常
     */
    public void truncate(_Table _table, MapSS replaceMap) throws ORMException, SQLException
    {
        ORM.as(_table != null?null:"ZTabler[truncate][表定义对象不能为null]");
        
        //组装SQL并执行
        String tableName = Sqls.formatReplaceMap(_table.getTable(), replaceMap);
        
        if (!server.isSqlite())
        {
            //创建表当不存在时
            create(_table, replaceMap);

            try
            {
                zSQL.execute("truncate table "+tableName);
            }
            catch(SQLException e)
            {
                if (!server.getPolicy().isTableNotExist(e))
                    throw e;
                
                //表不存在可能是缓存导致，重作一次
                tableExistList.remove(tableName);
                create(_table, replaceMap, true);
                zSQL.execute("truncate table "+tableName);
            }
        }
        else
        {//SQLite
            if (zSQL.existTable(tableName))
            {//先删表
                zSQL.execute("drop table "+tableName);
                tableExistList.remove(tableName);
            }
            
            //再重建表
            create(_table, replaceMap, true);
        }
    }
    
    /*****************************************************/
    //insert 插入数据
    /*****************************************************/

    /**
     * 增加数据，支持表或字段中中有多个替换字段，如LOG_TRACE_$MONTH$_$ID$
     * 
     * @param _table        表定义对象
     * @param data          表数据对象
     * @return              int 表示插入的条数
     * @throws ORMException 映射异常
     * @throws SQLException 数据库异常
     */
    public int insert(_Table _table, LinkedMapSO data) throws ORMException, SQLException
    {
        return insert(_table, data, null);
    }
    
    /**
     * 增加数据，支持表名中替换字段指定为$MONTH$，如LOG_TRACE$MONTH$
     * 
     * @param _table        表定义对象
     * @param data          表类
     * @param month         月份
     * @return              int 表示插入的条数
     * @throws ORMException 映射异常
     * @throws SQLException 数据库异常
     */
    public int insertMonth(_Table _table, LinkedMapSO data, String month) throws ORMException, SQLException
    {
        return insert(_table, data, new HashMapSS("MONTH", month));
    }
    
    /**
     * 增加数据，支持表或字段中中有多个替换字段，如LOG_TRACE_$MONTH$_$ID$
     * 
     * @param _table        表定义对象
     * @param data          表数据对象
     * @param replaceMap    适配表
     * @return              int 表示插入的条数
     * @throws ORMException 映射异常
     * @throws SQLException 数据库异常
     */
    public int insert(_Table _table, LinkedMapSO data, MapSS replaceMap) throws ORMException, SQLException
    {
        ORM.as(_table != null?null:"ZTabler[insert][表定义对象不能为null]");
        
        //创建表当不存在时
        create(_table, replaceMap);
        
        //组装SQL并把可能的field替换成column
        String sql = toInsertOrReplaceSQL(_table, "insert");
        replaceFieldToColumn(data, _table);
        
        try
        {//执行SQL
            return zSQL.executeUpdate(sql, data, replaceMap);
        }
        catch (TableNotExistException e) 
        {//表不存在重作一次（可能被管理员删除，对误操作增加的保险机制）
            create(_table, replaceMap, true);
            return zSQL.executeUpdate(sql, data, replaceMap);
        }
    }
    
    /**
     * 替换数据,传入标准[表类]对象和更新器（取fieldMap和replaceMap）当存在时指定修改的值
     * 
     * @param _table        表定义对象
     * @param data          表对象
     * @param updater       更新器
     * @return              int 表示插入的条数
     * @throws ORMException 映射异常
     * @throws SQLException 数据库异常
     */
    public int insertOrUpdate(_Table _table, LinkedMapSO data, Updater updater) throws ORMException, SQLException
    {
        ORM.as(_table != null?null:"ZTabler[insertOrUpdate][表定义对象不能为null]");
        
        if (!server.isMysql())
        {//只有MySQL支持
            throw new ORMException("ZTabler[insertOrUpdate]不支持当前数据库类型]");
        }
        
        //创建表当不存在时
        create(_table, updater.getReplaceMap());
        
        //组装字段和条件SQL和参数列
        MapSO paramMap = new HashMapSO();
        String insertSQL = toInsertOrUpdateSQL(_table, data, paramMap);
        String updateSQL = toUpdateFieldSQL(_table, updater, paramMap);
        
        //组装SQL
        StringBuilder sql = new StringBuilder(insertSQL).append(" on duplicate key update ").append(updateSQL);
        
        try
        {//执行SQL
            return zSQL.executeUpdate(sql.toString(), paramMap, updater.getReplaceMap());
        }
        catch (TableNotExistException e) 
        {//表不存在重作一次（可能被管理员删除，对误操作增加的保险机制）
            create(_table, updater.getReplaceMap(), true);
            return zSQL.executeUpdate(sql.toString(), paramMap, updater.getReplaceMap());
        }
    }
    
    /**
     * 批量增加数据
     * 
     * @param _table        表定义对象
     * @param dataList      表对象列表
     * @param replaceMap    适配表
     * @return              int 表示插入的条数
     * @throws ORMException 映射异常
     * @throws SQLException 数据库异常
     */
    public int[] insertBatch(_Table _table, List<LinkedMapSO> dataList) throws ORMException, SQLException
    {
        return insertBatch(_table, dataList, null);
    }
    
    /**
     * 批量增加数据，支持表或字段中中有多个替换字段，如LOG_TRACE_$MONTH$_$ID$
     * 
     * @param _table        表定义对象
     * @param dataList      表对象列表
     * @param replaceMap    适配表
     * @return              int 表示插入的条数
     * @throws ORMException 映射异常
     * @throws SQLException 数据库异常
     */
    public int[] insertBatch(_Table _table, List<LinkedMapSO> dataList, MapSS replaceMap) throws ORMException, SQLException
    {
        ORM.as(_table != null?null:"ZTabler[insertBatch][表定义对象不能为null]");
        
        if (dataList == null || dataList.isEmpty())
            return new int[0];
        
        //创建表当不存在时
        create(_table, replaceMap);
        
        //组装SQL
        String sql = toInsertOrReplaceSQL(_table, "insert");
        for (LinkedMapSO data : dataList)
        {
            replaceFieldToColumn(data, _table);
        }
        
        try
        {//执行SQL
            return zSQL.executeBatch(sql, dataList, replaceMap);
        }
        catch (TableNotExistException e) 
        {//表不存在重作一次（可能被管理员删除，对误操作增加的保险机制）
            create(_table, replaceMap, true);
            return zSQL.executeBatch(sql, dataList, replaceMap);
        }
    }
    
    /*****************************************************/
    //replace 替换数据，MYSQL支持，如果有数据先删除后增加
    /*****************************************************/
    
    /**
     * 替换数据,传入标准[表类]对象
     * 
     * @param _table        表定义对象
     * @param data          表对象
     * @return              int 表示插入的条数
     * @throws ORMException 映射异常
     * @throws SQLException 数据库异常
     */
    public int replace(_Table _table, LinkedMapSO data) throws ORMException, SQLException
    {
        return replace(_table, data, null);
    }

    /**
     * 替换数据，支持表名中替换字段指定为$MONTH$，如LOG_TRACE$MONTH$
     * 
     * @param _table        表定义对象
     * @param data          表对象
     * @param month         月份
     * @return int          表示插入的条数
     * @throws ORMException 映射异常
     * @throws SQLException 数据库异常
     */
    public int replaceMonth(_Table _table, LinkedMapSO data, String month) throws ORMException, SQLException
    {
        return replace(_table, data, new HashMapSS("MONTH", month));
    }
    
    /**
     * 替换数据，支持表或字段中有一个替换字段，如LOG_TRACE$ID$
     * 
     * @param _table        表定义对象
     * @param data          表对象
     * @param replaceKey    替换键
     * @param replaceValue  替换值
     * @return              int 表示插入的条数
     * @throws ORMException 映射异常
     * @throws SQLException 数据库异常
     */
    public int replace(_Table _table, LinkedMapSO data, String replaceKey, String replaceValue) throws ORMException, SQLException
    {
        return replace(_table, data, new HashMapSS(replaceKey, replaceValue));
    }
    
    /**
     * 替换数据，支持表或字段中中有多个替换字段，如LOG_TRACE_$MONTH$_$ID$
     * 
     * @param _table        表定义对象
     * @param data          表对象
     * @param replaceMap    适配表
     * @return              int 表示插入的条数
     * @throws ORMException 映射异常
     * @throws SQLException 数据库异常
     */
    public int replace(_Table _table, LinkedMapSO data, MapSS replaceMap) throws ORMException, SQLException
    {
        ORM.as(_table != null?null:"ZTabler[replace][表定义对象不能为null]");
        
        if (!server.isMysql() && !server.isSqlite())
        {//只有MySQL和SQLite支持replace
            throw new ORMException("ZTabler[replace]不支持当前数据库类型]");
        }
        
        //创建表当不存在时
        create(_table, replaceMap);
        
        //组装SQL
        String sql = toInsertOrReplaceSQL(_table, "replace");
        replaceFieldToColumn(data, _table);
        
        try
        {//执行SQL
            return zSQL.executeUpdate(sql, data, replaceMap);
        }
        catch (TableNotExistException e) 
        {//表不存在重作一次（可能被管理员删除，对误操作增加的保险机制）
            create(_table, replaceMap, true);
            return zSQL.executeUpdate(sql, data, replaceMap);
        }
    }

    /**
     * 批量替换数据
     * 
     * @param _table        表定义对象
     * @param dataList      表对象列表
     * @return              int 表示插入的条数
     * @throws ORMException 映射异常
     * @throws SQLException 数据库异常
     */
    public int[] replaceBatch(_Table _table, List<LinkedMapSO> dataList) throws ORMException, SQLException
    {
        return replaceBatch(_table, dataList, null);
    }
    
    /**
     * 批量替换数据，支持表或字段中中有多个替换字段，如LOG_TRACE_$MONTH$_$ID$
     * 
     * @param _table        表定义对象
     * @param dataList      表对象列表
     * @param replaceMap    适配表
     * @return              int 表示插入的条数
     * @throws ORMException 映射异常
     * @throws SQLException 数据库异常
     */
    public int[] replaceBatch(_Table _table, List<LinkedMapSO> dataList, MapSS replaceMap) throws ORMException, SQLException
    {
        ORM.as(_table != null?null:"ZTabler[replaceBatch][表定义对象不能为null]");
        
        if (!server.isMysql() && !server.isSqlite())
        {//只有MySQL和SQLite支持replace
            throw new ORMException("ZTabler[replaceBatch]不支持当前数据库类型]");
        }
        
        if (dataList == null || dataList.isEmpty())
            return new int[0];
        
        //创建表当不存在时
        create(_table, replaceMap);
        
        //组装SQL
        String sql = toInsertOrReplaceSQL(_table, "replace");
        for (LinkedMapSO data : dataList)
        {
            replaceFieldToColumn(data, _table);
        }
        
        try
        {//执行SQL
            return zSQL.executeBatch(sql, dataList, replaceMap);
        }
        catch (TableNotExistException e) 
        {//表不存在重作一次（可能被管理员删除，对误操作增加的保险机制）
            create(_table, replaceMap, true);
            return zSQL.executeBatch(sql, dataList, replaceMap);
        }
    }
    
    /*****************************************************/
    //update 更新数据
    /*****************************************************/
    
    /**
     * 更新数据，指定更新器需要更新的字段、条件和可替换表
     * 
     * @param _table        表定义对象
     * @param updater       更新器
     * @return              int 表示更新的条数
     * @throws ORMException 映射异常
     * @throws SQLException 数据库异常
     */
    public int update(_Table _table, Updater updater) throws ORMException, SQLException
    {
        ORM.as(_table != null?null:"ZTabler[update][表定义对象不能为null]");
        ORM.as(updater != null?null:"ZTabler[update][updater不允许为null]");
        
        //创建表当不存在时
        create(_table, updater.getReplaceMap());
        
        //组装字段和条件SQL和参数列
        MapSO paramMap = new HashMapSO();
        String fieldSQL = toUpdateFieldSQL(_table, updater, paramMap);
        String whereSQL = updater.getWhereSQL(_table, paramMap);
        
        //组装SQL
        StringBuilder sql = new StringBuilder("update ").append(_table.getTable()).append(" set ");
        sql.append(fieldSQL);
        sql.append(whereSQL);
        
        try
        {//执行SQL
            return zSQL.executeUpdate(sql.toString(), paramMap, updater.getReplaceMap());
        }
        catch (TableNotExistException e) 
        {//表不存在重作一次（可能被管理员删除，对误操作增加的保险机制）
            create(_table, updater.getReplaceMap(), true);
            return zSQL.executeUpdate(sql.toString(), paramMap, updater.getReplaceMap());
        }
    }
    
    /**
     * 更新数据，指定对象，根据主键进行更新，主键值不更新
     * 
     * @param _table        表定义对象
     * @param data          表对象
     * @return              int 表示更新的条数
     * @throws ORMException 映射异常
     * @throws SQLException 数据库异常
     */
    public int update(_Table _table, LinkedMapSO data) throws ORMException, SQLException
    {
        return update(_table, data, null);
    }
    
    /**
     * 更新数据，指定对象，根据主键进行更新，主键值不更新，支持表名中替换字段指定为$MONTH$，如LOG_TRACE$MONTH$
     * 
     * @param _table        表定义对象
     * @param data          表对象
     * @param month         月份
     * @return              int 表示更新的条数
     * @throws ORMException 映射异常
     * @throws SQLException 数据库异常
     */
    public int updateMonth(_Table _table, LinkedMapSO data, String month) throws ORMException, SQLException
    {
        return update(_table, data, new HashMapSS("MONTH", month));
    }
    
    /**
     * 更新数据，指定对象，根据主键进行更新，主键值不更新，支持表或字段中有一个替换字段，如LOG_TRACE$ID$
     * 
     * @param _table        表定义对象
     * @param data          表对象
     * @param replaceKey    替换键
     * @param replaceValue  替换值
     * @return              int 表示更新的条数
     * @throws ORMException 映射异常
     * @throws SQLException 数据库异常
     */
    public int update(_Table _table, LinkedMapSO data, String replaceKey, String replaceValue) throws ORMException, SQLException
    {
        return update(_table, data, new HashMapSS(replaceKey, replaceValue));
    }
    
    /**
     * 更新数据，指定对象，根据主键进行更新，主键值不更新，支持可替换表
     * 
     * @param _table        表定义对象
     * @param data          表对象
     * @param replaceMap    适配表
     * @return              int 表示更新的条数
     * @throws ORMException 映射异常
     * @throws SQLException 数据库异常
     */
    public int update(_Table _table, LinkedMapSO data, MapSS replaceMap) throws ORMException, SQLException
    {
        ORM.as(_table != null?null:"ZTabler[update][表定义对象不能为null]");
        ORM.as(!_table.isAllKey()?null:"ZTabler[update]["+_table.getName()+"]所有字段都是关键属性,不支持此更新方法");
        
        //创建表当表不存在时
        create(_table, replaceMap);
        
        //组装SQL
        StringBuilder sql = new StringBuilder("update ").append(_table.getTable()).append(" set ");
        //field
        List<_TableField> fieldList = _table.getFieldListNoKey();
        //第一个不加逗号
        _TableField field = fieldList.get(0);
        sql.append(field.getColumn()).append("=#").append(field.getColumn()).append("#");
        //后面的加逗号
        for (int i=1;i<fieldList.size();i++)
        {
            field = fieldList.get(i);
            sql.append(", ").append(field.getColumn()).append("=#").append(field.getColumn()).append("#");
        }
        
        //where
        List<String> keyList = _table.getKeyList();
        //第一个不加 where
        StringBuilder where = new StringBuilder();
        where.append(" where ").append(keyList.get(0)).append("=#").append(keyList.get(0)).append("#");
        //后面的加 and
        for (int i=1;i<keyList.size();i++)
        {
            where.append(" and ").append(keyList.get(i)).append("=#").append(keyList.get(i)).append("#");
        }
        sql.append(where);
        
        //替换字段为表列名
        replaceFieldToColumn(data, _table);
        
        try
        {//执行SQL
            return zSQL.executeUpdate(sql.toString(), data, replaceMap);
        }
        catch (TableNotExistException e) 
        {//表不存在重作一次（可能被管理员删除，对误操作增加的保险机制）
            create(_table, replaceMap, true);
            return zSQL.executeUpdate(sql.toString(), data, replaceMap);
        }
    }
    
    /*****************************************************/
    //delete 删除数据
    /*****************************************************/
    
    /**
     * 删除数据，多个主键时使用
     * 
     * @param _table        表定义对象
     * @param ids           关键属性为数组，多个主键
     * @return              返回删除数
     * @throws ORMException 映射异常
     * @throws SQLException 数据库异常
     */
    public int delete(_Table _table, Object... ids) throws ORMException, SQLException
    {
        return delete(_table, null, ids);
    }
    
    /**
     * 删除数据，多个主键时使用
     * 
     * @param _table        表定义对象
     * @param replaceMap    替换表
     * @param ids           关键属性为数组，多个主键
     * @return              返回删除数
     * @throws ORMException 映射异常
     * @throws SQLException 数据库异常
     */
    public int delete(_Table _table, MapSS replaceMap, Object... ids) throws ORMException, SQLException
    {
        ORM.as(_table != null?null:"ZTabler[delete][表定义对象不能为null]");
        ORM.as(!_table.isAllKey()?null:"ZTabler[delete]["+_table.getName()+"][传参与主键要求不匹配]");
        
        //创建表当表不存在时
        create(_table, replaceMap);
        
        //组装SQL
        StringBuilder sql = new StringBuilder("delete from ");

        String[] keyArr = _table.getKeyArr();
        sql.append(_table.getTable()).append(" where ").append(keyArr[0]).append("=?");
        for (int i=1;i<keyArr.length;i++)
        {
            sql.append(" and ").append(keyArr[i]).append("=?");
        }
        
        try
        {//执行SQL
            return zSQL.executeUpdate(sql.toString(), ids, replaceMap);
        }
        catch (TableNotExistException e) 
        {//表不存在重作一次（可能被管理员删除，对误操作增加的保险机制）
            create(_table, replaceMap, true);
            return zSQL.executeUpdate(sql.toString(), ids, replaceMap);
        }
    }
    
    /**
     * 删除数据, 根据条件
     * 
     * @param _table        表定义对象
     * @param selector      对象选择器
     * @return              返回删除数
     * @throws ORMException 映射异常
     * @throws SQLException 数据库异常
     */
    public int delete(_Table _table, Selector selector) throws ORMException, SQLException
    {
        ORM.as(_table != null?null:"ZTabler[delete][表定义对象不能为null]");
        ORM.as(selector != null?null:"ZTabler[delete][selector不允许为null]");
        
        //创建表当不存在时
        create(_table, selector.getReplaceMap());
        
        //组装SQL
        MapSO paramMap = new HashMapSO();
        StringBuilder sql = new StringBuilder("delete from ");
        sql.append(_table.getTable());
        sql.append(selector.getWhereSQL(_table, paramMap));
        
        try
        {//执行SQL
            return zSQL.executeUpdate(sql.toString(), paramMap, selector.getReplaceMap());
        }
        catch (TableNotExistException e) 
        {//表不存在重作一次（可能被管理员删除，对误操作增加的保险机制）
            create(_table, selector.getReplaceMap(), true);
            return zSQL.executeUpdate(sql.toString(), paramMap, selector.getReplaceMap());
        }
    }
    
    /**
     * 批量删除数据，多个主键时使用
     * 
     * @param _table        表定义对象
     * @param idsList       关键属性为数组，多个主键的列表
     * @return              返回删除数列表
     * @throws ORMException 映射异常
     * @throws SQLException 数据库异常
     */
    public int[] deleteBatch(_Table _table, List<Object[]> idsList) throws ORMException, SQLException
    {
        return deleteBatch(_table, null, idsList);
    }
    
    /**
     * 批量删除数据，多个主键时使用
     * 
     * @param _table        表定义对象
     * @param replaceMap    替换表
     * @param idsList       关键属性为数组，多个主键的列表
     * @return              返回删除数列表
     * @throws ORMException 映射异常
     * @throws SQLException 数据库异常
     */
    public int[] deleteBatch(_Table _table, MapSS replaceMap, List<Object[]> idsList) throws ORMException, SQLException
    {
        ORM.as(_table != null?null:"ZTabler[deleteBatch][表定义对象不能为null]");
        
        if (idsList == null || idsList.isEmpty())
            return new int[0];
        
        ORM.as(_table.isValidKeyObj(idsList.get(0))?null:"ZTabler[deleteBatch]["+_table.getName()+"][传参与主键要求不匹配]");
        
        //创建表当表不存在时
        create(_table, replaceMap);
        
        //组装SQL
        StringBuilder sql = new StringBuilder("delete from ");

        String[] keyArr = _table.getKeyArr();
        sql.append(_table.getTable()).append(" where ").append(keyArr[0]).append("=?");
        for (int i=1;i<keyArr.length;i++)
        {
            sql.append(" and ").append(keyArr[i]).append("=?");
        }
        
        try
        {//执行SQL
            return zSQL.executeBatch(sql.toString(), idsList, replaceMap);
        }
        catch (TableNotExistException e) 
        {//表不存在重作一次（可能被管理员删除，对误操作增加的保险机制）
            create(_table, replaceMap, true);
            return zSQL.executeBatch(sql.toString(), idsList, replaceMap);
        }
    }
    
    /*****************************************************/
    //count 查询数目
    /*****************************************************/
    
    /**
     * 查询数目，多个主键时使用
     * 
     * @param _table        表定义对象
     * @param ids           关键属性值，支持多个
     * @return              存在的数目
     * @throws ORMException 映射异常
     * @throws SQLException 数据库异常
     */
    public int count(_Table _table, Object... ids) throws ORMException, SQLException
    {
        ORM.as(_table != null?null:"ZTabler[count][表定义对象不能为null]");
        ORM.as(_table.isValidKeyObj(ids)?null:"ZTabler[count][传参与主键要求不匹配]");
        
        //创建表当不存在时
        create(_table);
        
        //组装SQL
        StringBuilder sql = new StringBuilder("select count(*) from ").append(_table.getTable());

        String[] keyArr = _table.getKeyArr();
        //第一个where
        sql.append(" where ").append(keyArr[0]).append("=?");
        //后面的and
        for (int i=1;i<keyArr.length;i++)
        {
            sql.append(" and ").append(keyArr[i]).append("=?");
        }
        
        try
        {//执行SQL
            List<Integer> list = zSQL.executeQuery(sql.toString(), Integer.class, ids);
            return list.get(0);
        }
        catch (TableNotExistException e) 
        {//表不存在重作一次（可能被管理员删除，对误操作增加的保险机制）
            create(_table, true);
            List<Integer> list = zSQL.executeQuery(sql.toString(), Integer.class, ids);
            return list.get(0);
        }
    }

    /**
     * 查询数目，整表查询
     * 
     * @param _table        表定义对象
     * @return              int 数目值
     * @throws ORMException 映射异常
     * @throws SQLException 数据库异常
     */
    public int count(_Table _table) throws ORMException, SQLException
    {
        ORM.as(_table != null?null:"ZTabler[count][表定义对象不能为null]");
        
        //创建表当不存在时
        create(_table);
        
        //组装SQL
        String sql = "select count(*) from "+_table.getTable();
        
        try
        {//执行SQL
            List<Integer> list = zSQL.executeQuery(sql, Integer.class);
            return list.get(0);
        }
        catch (TableNotExistException e) 
        {//表不存在重作一次（可能被管理员删除，对误操作增加的保险机制）
            create(_table, true);
            List<Integer> list = zSQL.executeQuery(sql, Integer.class);
            return list.get(0);
        }
    }
    
    /**
     * 查询数目，根据条件、可替换表查询
     * 
     * @param _table        表定义对象
     * @param selector      对象查询器
     * @return              int 数目值
     * @throws ORMException 映射异常
     * @throws SQLException 数据库异常
     */
    public int count(_Table _table, Selector selector)throws ORMException, SQLException
    {
        ORM.as(_table != null?null:"ZTabler[count][表定义对象不能为null]");
        ORM.as(selector != null?null:"ZTabler[count][selector不允许为null]");
        
        //创建表当不存在时
        create(_table, selector.getReplaceMap());
        
        //组装SQL
        MapSO paramMap = new HashMapSO();
        String whereSQL = selector.getWhereSQL(_table, paramMap);
        StringBuilder sql = new StringBuilder("select count(*) from ").append(_table.getTable()).append(whereSQL);
        
        try
        {//执行SQL
            List<Integer> list = zSQL.executeQuery(sql.toString(), Integer.class, paramMap, selector.getReplaceMap());
            return list.get(0);
        }
        catch (TableNotExistException e) 
        {//表不存在重作一次（可能被管理员删除，对误操作增加的保险机制）
            create(_table, selector.getReplaceMap(), true);
            List<Integer> list = zSQL.executeQuery(sql.toString(), Integer.class, paramMap, selector.getReplaceMap());
            return list.get(0);
        }
    }
    
    /**
     * 分组查询数目，根据条件、可替换表和分组字段
     * 
     * @param cls           表类
     * @param selector
     * @return
     * @throws ORMException
     * @throws SQLException
     */
    public List<MapSO> countGroupBy(_Table _table, Selector selector) throws ORMException, SQLException
    {
        ORM.as(_table != null?null:"ZTabler[countGroupBy][表定义对象不能为null]");
        ORM.as(selector != null?null:"ZTabler[countGroupBy][selector不允许为null]");
        ORM.as(!Validates.isEmpty(selector.getGroupby())?null:"ZTabler[countGroupBy][groupby不允许为null]");
        
        //创建表当不存在时
        create(_table, selector.getReplaceMap());
        
        //组装SQL
        MapSO paramMap = new HashMapSO();
        String groupbyFieldsSQL = selector.getGroupbyFieldsSQL(_table);
        String whereSQL = selector.getWhereSQL(_table, paramMap);
        String groupbySQL = selector.getGroupbySQL(_table);
        StringBuilder sql = new StringBuilder("select ").append(groupbyFieldsSQL).append(", count(*) as _COUNT_ from ")
                                                        .append(_table.getTable())
                                                        .append(whereSQL).append(groupbySQL);
        
        try
        {//执行SQL
            return zSQL.executeQuery(sql.toString(), MapSO.class, paramMap, selector.getReplaceMap());
        }
        catch (TableNotExistException e) 
        {//表不存在重作一次（可能被管理员删除，对误操作增加的保险机制）
            create(_table, selector.getReplaceMap(), true);
            return zSQL.executeQuery(sql.toString(), MapSO.class, paramMap, selector.getReplaceMap());
        }
    }
    
    /*****************************************************/
    //sum 计算总和
    /*****************************************************/
    
    /**
     * 计算总和
     * 
     * @param _table        表定义对象
     * @param field         表字段
     * @return              计算总和
     * @throws ORMException 映射异常
     * @throws SQLException 数据库异常
     */
    public long sum(_Table _table, String field) throws ORMException, SQLException
    {
        return sum(_table, new Selector(), field);
    }
    
    /**
     * 计算总和
     * 
     * @param _table        表定义对象
     * @param selector      对象查询器
     * @param field         表字段
     * @return              计算总和
     * @throws ORMException 映射异常
     * @throws SQLException 数据库异常
     */
    public long sum(_Table _table, Selector selector, String field) throws ORMException, SQLException
    {
        ORM.as(_table != null?null:"ZTabler[sum][表定义对象不能为null]");
        
        String column = _table.getColumn(field);
        if (column == null)
            throw new ORMException("ZTabler[sum]["+_table.getName()+"]配置中未找到["+field+"]字段");
        
        //创建表当不存在时
        create(_table, selector.getReplaceMap());
        
        //组装SQL
        MapSO paramMap = new HashMapSO();
        String whereSQL = selector.getWhereSQL(_table, paramMap);
        StringBuilder sql = new StringBuilder("select sum(").append(column).append(") from ").append(_table.getTable()).append(whereSQL);
        
        try
        {//执行SQL
            List<Long> list = zSQL.executeQuery(sql.toString(), Long.class, paramMap, selector.getReplaceMap());
            return list.isEmpty()?0:list.get(0);
        }
        catch (TableNotExistException e) 
        {//表不存在重作一次（可能被管理员删除，对误操作增加的保险机制）
            create(_table, selector.getReplaceMap(), true);
            List<Long> list = zSQL.executeQuery(sql.toString(), Long.class, paramMap, selector.getReplaceMap());
            return list.isEmpty()?0:list.get(0);
        }
    }
    
    /**
     * 计算多个总和
     * 
     * @param _table        表定义对象
     * @param selector      对象查询器
     * @param fields        多个表字段
     * @return              计算多个总和
     * @throws ORMException 映射异常
     * @throws SQLException 数据库异常
     */
    public long[] sum(_Table _table, Selector selector, String... fields) throws ORMException, SQLException
    {
        ORM.as(_table != null?null:"ZTabler[sum][表定义对象不能为null]");
        ORM.as(selector != null?null:"ZTabler[sum][selector不允许为null]");
        
        if (fields == null || fields.length < 1)
            throw new ORMException("ZTabler[sum][fieldArr]不能为空]");
        
        if (!_table.hasAllField(fields))
            throw new ORMException("ZTabler[sum]["+Arrays.toString(fields)+"]有未找到的字段");
        
        create(_table, selector.getReplaceMap());
        
        //组装SQL
        StringBuilder sql = new StringBuilder("select ");
        //第一个
        String column = _table.getColumn(fields[0]);
        sql.append(" sum(").append(column).append(") as ").append(fields[0]);
        //后面的
        for (int i=1;i<fields.length;i++)
        {
            column = _table.getColumn(fields[i]);
            sql.append(", sum(").append(column).append(") as ").append(fields[i]);
        }
        
        MapSO paramMap = new HashMapSO();
        String whereSQL = selector.getWhereSQL(_table, paramMap);
        sql.append(" from ").append(_table.getTable()).append(whereSQL);
        
        List<LinkedMapSO> list = null;
        try
        {//执行SQL
            list = zSQL.executeQuery(sql.toString(), LinkedMapSO.class, paramMap, selector.getReplaceMap());
        }
        catch (TableNotExistException e) 
        {//表不存在重作一次（可能被管理员删除，对误操作增加的保险机制）
            create(_table, selector.getReplaceMap(), true);
            list = zSQL.executeQuery(sql.toString(), LinkedMapSO.class, paramMap, selector.getReplaceMap());
        }
        
        if (list.isEmpty())
            return new long[fields.length];

        //对结果集处理
        LinkedMapSO item = list.get(0);
        long[] valueArr = new long[fields.length];
        for (int i=0;i<fields.length;i++)
        {//默认为数值型，需要转化为long
            BigDecimal value = (BigDecimal)item.get(fields[i]);
            if (value == null)
                valueArr[i] = 0;
            else
                valueArr[i] = value.longValue();
        }
        return valueArr;
    }
    
    /*****************************************************/
    //item 查询一条数据
    /*****************************************************/
    
    /**
     * 查询一个表对象，支持多个主键
     * 
     * @param _table        表定义实例
     * @param ids           关键属性值
     * @return              返回表对象
     * @throws ORMException 映射异常
     * @throws SQLException 数据库异常
     */
    public LinkedMapSO item(_Table _table, Object... ids) throws ORMException, SQLException
    {
        ORM.as(_table != null?null:"ZTabler[item][表定义对象不能为null]");
        ORM.as(_table.isValidKeyObj(ids)?null:"ZTabler[item][传参与主键要求不匹配]");
        
        //创建表当表不存在时
        create(_table);
        
        StringBuilder sql = new StringBuilder("select * from ").append(_table.getTable());

        String[] keyArr = _table.getKeyArr();
        //第一个where
        sql.append(" where ").append(keyArr[0]).append("=?");
        //后面的and
        for (int i=1;i<keyArr.length;i++)
        {
            sql.append(" and ").append(keyArr[i]).append("=?");
        }
        
        try
        {//执行SQL
            List<LinkedMapSO> list = zSQL.executeQuery(sql.toString(), LinkedMapSO.class, ids);
            return list.isEmpty()?null:list.get(0);
        }
        catch (TableNotExistException e) 
        {//表不存在重作一次（可能被管理员删除，对误操作增加的保险机制）
            create(_table, true);
            List<LinkedMapSO> list = zSQL.executeQuery(sql.toString(), LinkedMapSO.class, ids);
            return list.isEmpty()?null:list.get(0);
        }
    }
    
    /**
     * 查询一个表对象，并指定返回属性,查询第一行
     * 
     * @param _table        表定义实例
     * @return              返回表对象
     * @throws ORMException 映射异常,如果传入的属性不在配置文件中则异常
     * @throws SQLException 数据库异常
     */
    public LinkedMapSO item(_Table _table) throws ORMException, SQLException
    {
        return item(_table, new Selector());
    }
    
    /**
     * 查询一个表对象，并指定返回属性,查询条件和排序条件
     * 
     * @param _table        表定义实例
     * @param selector      对象查询器
     * @return              返回表对象
     * @throws ORMException 映射异常,如果传入的属性不在配置文件中则异常
     * @throws SQLException 数据库异常
     */
    public LinkedMapSO item(_Table _table, Selector selector) throws ORMException, SQLException
    {
        ORM.as(_table != null?null:"ZTabler[item][表定义对象不能为null]");
        
        //创建表当不存在时
        create(_table, selector.getReplaceMap());
        
        //组装SQL
        MapSO paramMap = new HashMapSO();
        String fieldSQL = selector.getFieldSQL(_table);
        String whereSQL = selector.getWhereSQL(_table, paramMap);
        String orderbySQL = selector.getOrderbySQL(_table);
        String groupbySQL = selector.getGroupbySQL(_table);
        String sql = server.getPolicy().toItemSQL(fieldSQL, _table.getTable(), whereSQL, orderbySQL, groupbySQL);
        
        try
        {//执行SQL
            List<LinkedMapSO> list = zSQL.executeQuery(sql, LinkedMapSO.class, paramMap, selector.getReplaceMap());
            return list.isEmpty()?null:list.get(0);
        }
        catch (TableNotExistException e) 
        {//表不存在重作一次（可能被管理员删除，对误操作增加的保险机制）
            create(_table, selector.getReplaceMap(), true);
            List<LinkedMapSO> list = zSQL.executeQuery(sql, LinkedMapSO.class, paramMap, selector.getReplaceMap());
            return list.isEmpty()?null:list.get(0);
        }
    }

    /*****************************************************/
    //list 查询列表
    /*****************************************************/
    
    /**
     * 查询表对象列表，全表查询
     * 
     * @param _table        表定义对象
     * @return              返回表对象列表
     * @throws ORMException 映射异常
     * @throws SQLException 数据库异常
     */
    public List<LinkedMapSO> list(_Table _table) throws ORMException, SQLException
    {
        return list(_table, new Selector());
    }
    
    /**
     * 查询表对象列表，并指定返回属性,查询条件和排序条件
     * 
     * @param _table        表定义对象
     * @param selector      对象查询器
     * @return              返回表对象列表
     * @throws ORMException 映射异常,如果传入的属性不在配置文件中则异常
     * @throws SQLException 数据库异常
     */
    public List<LinkedMapSO> list(_Table _table, Selector selector) throws ORMException, SQLException
    {
        ORM.as(_table != null?null:"ZTabler[list][表定义对象不能为null]");
        ORM.as(selector != null?null:"ZTabler[list][selector不允许为null]");
        
        //创建表当不存在时
        create(_table, selector.getReplaceMap());
        
        //组装SQL
        MapSO paramMap = new HashMapSO();
        String fieldSQL = selector.getFieldSQL(_table);
        String whereSQL = selector.getWhereSQL(_table, paramMap);
        String orderbySQL = selector.getOrderbySQL(_table);
        String groupbySQL = selector.getGroupbySQL(_table);
        StringBuilder sql = new StringBuilder("select ").append(fieldSQL).append(" from ").append(_table.getTable()).append(whereSQL).append(orderbySQL).append(groupbySQL);
        
        try
        {//执行SQL
            return zSQL.executeQuery(sql.toString(), LinkedMapSO.class, paramMap, selector.getReplaceMap());
        }
        catch (TableNotExistException e) 
        {//表不存在重作一次（可能被管理员删除，对误操作增加的保险机制）
            create(_table, selector.getReplaceMap(), true);
            return zSQL.executeQuery(sql.toString(), LinkedMapSO.class, paramMap, selector.getReplaceMap());
        }
    }
    
    /**
     * 查询表对象列表，查询指定的位置的数据
     * 
     * @param _table        表定义对象
     * @param pageNo        页码
     * @param pageSize      页数
     * @return              返回表对象列表
     * @throws ORMException 映射异常
     * @throws SQLException 数据库异常
     */
    public List<LinkedMapSO> list(_Table _table, int pageNo, int pageSize) throws ORMException, SQLException
    {
        return list(_table, pageNo, pageSize, new Selector());
    }
    
    /**
     * 查询表对象列表，并指定位置的,条件和排序条件
     * 
     * @param _table        表定义对象
     * @param pageNo        页码
     * @param pageSize      页数
     * @param selector      对象查询器
     * @return              返回表对象列表
     * @throws ORMException 映射异常,如果传入的属性不在配置文件中则异常
     * @throws SQLException 数据库异常
     */
    public List<LinkedMapSO> list(_Table _table, int pageNo, int pageSize, Selector selector) throws ORMException, SQLException
    {
        ORM.as(_table != null?null:"ZTabler[list][表定义对象不能为null]");
        ORM.as(selector != null?null:"ZTabler[list][selector不允许为null]");
        
        //创建表当不存在时
        create(_table, selector.getReplaceMap());
        
        if (pageNo < 1) pageNo = 1;
        if (pageSize < 1) pageSize = 10;
        
        //执行SQL
        return lister(_table, pageNo, pageSize, selector);
    }
    
    /*****************************************************/
    //page 分页显示
    /*****************************************************/
    
    /**
     * 查询表对象分页信息
     * 
     * @param _table        表定义对象
     * @param pageNo        页码
     * @param pageSize      页数
     * @return              分页信息,包括总页数,页码,页数和查询的记录
     * @throws ORMException 映射异常
     * @throws SQLException 数据库异常
     */
    public PageResult<LinkedMapSO> page(_Table _table, int pageNo, int pageSize) throws ORMException, SQLException
    {
        return page(_table, pageNo, pageSize, new Selector());
    }

    /**
     * 查询表对象分页信息
     * 
     * @param _table        表定义对象
     * @param pageNo        页码
     * @param pageSize      页数
     * @param selector      对象查询器
     * @return              分页信息,包括总页数,页码,页数和查询的记录
     * @throws ORMException 映射异常
     * @throws SQLException 数据库异常
     */
    public PageResult<LinkedMapSO> page(_Table _table, int pageNo, int pageSize, Selector selector) throws ORMException, SQLException
    {
        ORM.as(_table != null?null:"ZTabler[page][表定义对象不能为null]");
        ORM.as(selector != null?null:"ZTabler[page][selector不允许为null]");
        
        //检查和尝试创建表
        create(_table, selector.getReplaceMap());
        
        if (pageNo < 1) pageNo = 1;
        if (pageSize < 1) pageSize = 10;
        
        int totalRecord = count(_table, selector);
        if (totalRecord == 0)
            return PageBuilder.newResult(pageNo, pageSize);
        
        //检查where
        int maxPage = (totalRecord-1) / pageSize + 1;
        if (pageNo > maxPage) pageNo = maxPage;
        
        //执行SQL
        List<LinkedMapSO> list = lister(_table, pageNo, pageSize, selector);
        return PageBuilder.newResult(totalRecord, pageNo, pageSize, list);
    }

    
    /**************************************************************************/
    //内部ZTable & ZTabler调用的方法
    /**************************************************************************/
    
    /**
     * 通过表定义对象，组装插入或替换的SQL
     * 1.insert & insertOrUpdate & insertBatch
     * 2.replace & replaceBatch
     * 调用
     * 
     * @param _table        表定义对象
     * @param statement     insert & replace
     * @return              SQL语句
     */
    public String toInsertOrReplaceSQL(_Table _table, String statement)
    {
        //组装SQL
        StringBuilder sql = new StringBuilder(statement).append(" into ").append(_table.getTable()).append("(");
        StringBuilder values = new StringBuilder("values (");
        List<_TableField> fieldList = _table.getFieldList();
        for (_TableField field : fieldList)
        {
            sql.append(field.getColumn()).append(",");
            values.append("#").append(field.getColumn()).append("#").append(",");
        }
        
        //去除最后一个逗号
        sql.setLength(sql.length()-1);
        values.setLength(values.length()-1);
        
        //最后加结尾
        sql.append(") ").append(values).append(")");
        
        return sql.toString();
    }
    
    /**
     * 通过表定义对象，组装插入或更新的SQL
     * 1.insert & insertOrUpdate & insertBatch
     * 2.replace & replaceBatch
     * 调用
     * 
     * @param _table        表定义对象
     * @param data          对象
     * @param paramMap      得到参数表
     * @return              SQL语句
     * @throws ORMException 异常
     */
    private String toInsertOrUpdateSQL(_Table _table, LinkedMapSO data, MapSO paramMap) throws ORMException
    {
        //组装SQL
        StringBuilder sql = new StringBuilder("insert into ").append(_table.getTable()).append("(");
        StringBuilder values = new StringBuilder("values (");
        List<_TableField> fieldList = _table.getFieldList();
        for (_TableField field : fieldList)
        {
            String column = field.getColumn();
            
            paramMap.put(column, data.get(column));
            sql.append(column).append(",");
            values.append("#").append(column).append("#").append(",");
        }
        
        //去除最后一个逗号
        sql.setLength(sql.length()-1);
        values.setLength(values.length()-1);
        
        //最后加结尾
        sql.append(") ").append(values).append(")");
        
        return sql.toString();
    }
    
    /**
     * 通过表定义对象，组装更新字段SQL
     * update & insertOrUpdate调用
     * 
     * @param _table            表对象
     * @param updater           更新器
     * @param paramMap          参数表
     * @return                  SQL语句
     * @throws ORMException     映射异常
     */
    public String toUpdateFieldSQL(_Table _table, Updater updater, MapSO paramMap) throws ORMException
    {
        StringBuilder sql = new StringBuilder();
        for (UpdaterField field : updater.getFieldList().values())
        {
            if (!_table.hasField(field.getField()))
                throw new ORMException("ZTabler[toUpdateFieldSQL]["+_table.getName()+"]配置中未找到["+field.getField()+"]字段");
            
            String column = _table.getColumn(field.getField());
            if (field.getType() == 0)
            {//值类型
                paramMap.put(column, field.getValue());
                sql.append(column).append("=#").append(column).append("#,");
            }
            else
            {//表达式类型
                String value = (String)field.getValue();
                
                //对value中可能出现的字段进行匹配，替换成表列，注意有可能第二个列名会包含第一个列名，因此处理时字段名从长到短进行匹配
                _TableField[] dboFieldArr = _table.getFieldColumnListOrderByLen();
                for (_TableField dboField : dboFieldArr)
                {//依次从长到短对表达式中的字段替换成表列 TODO 暂不对$等可能替换成错进行处理
                    value = value.replaceAll(dboField.getField(), dboField.getColumn());
                }
                
                sql.append(column).append("=").append(value).append(",");
            }
        }
        
        //如果有值去掉最后的逗号
        if (sql.length() > 0)
            sql.setLength(sql.length()-1);
        
        return sql.toString();
    }
    
    /** 内部方法，list & page 调用 */
    private List<LinkedMapSO> lister(_Table _table, int pageNo, int pageSize, Selector selector) throws ORMException, SQLException
    {
        int minNum = (pageNo-1) * pageSize + 1;
        int maxNum = pageNo * pageSize;
        
        MapSO paramMap = new HashMapSO();
        paramMap.put("minNum", minNum);
        paramMap.put("maxNum", maxNum);
        paramMap.put("minSize", minNum - 1);
        paramMap.put("pageSize", pageSize);
        
        //组装SQL
        String fieldSQL = selector.getFieldSQL(_table);
        String whereSQL = selector.getWhereSQL(_table, paramMap);
        String orderbySQL = selector.getOrderbySQL(_table);
        String groupbySQL = selector.getGroupbySQL(_table);
        String sql = server.getPolicy().toPageSQL(fieldSQL, _table.getTable(), whereSQL, orderbySQL, groupbySQL, maxNum, pageNo);
        
        try
        {//执行SQL
            return zSQL.executeQuery(sql, LinkedMapSO.class, paramMap, selector.getReplaceMap());
        }
        catch (TableNotExistException e) 
        {//表不存在重作一次（可能被管理员删除，对误操作增加的保险机制）
            create(_table, selector.getReplaceMap(), true);
            return zSQL.executeQuery(sql, LinkedMapSO.class, paramMap, selector.getReplaceMap());
        }
    }
    
    /**
     * 替换字段名为列名
     * 
     * @param _table    表定义对象
     * @return          本身
     */
    private void replaceFieldToColumn(LinkedMapSO data, _Table _table)
    {
        String[] keys = Lists.toArray(data.keySet(), new String[0]);
        for (String key : keys)
        {
            String column = _table.getColumn(key);
            Asserts.assertNotNull(column, ORMI18n.ormTableNotFoundField2, _table.getName(), key);
            
            if (column.equals(key))
                continue;
            
            //把field替换成column
            data.put(column, data.get(key));
            data.remove(key);
        }
    }
    
    /** 获取表锁 */
    private Object getTableLock(String tableName)
    {
        Object lock = tableLockMap.get(tableName);
        if (lock != null)
            return lock;
        
        synchronized (tableLockMap)
        {
            lock = tableLockMap.get(tableName);
            if (lock != null)
                return lock;
            
            lock = new Object();
            tableLockMap.put(tableName, lock);
            return lock;
        }
    }
}
